﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HitachiLib.Data;
using HitachiLib.HitachiServiceRef;
using HitachiLib.Utils;

namespace HitachiApp.Model
{
    public class ScheduleTabViewModel : INotifyPropertyChanged
    {
        private ProjectSelectorControlModel project_selector_control_model;

        private ProjectListViewModel unscheduled_project_model;
        private ProjectListViewModel all_project_model;

        private List<ScheduleListViewModel> common_schedule_model_list = new List<ScheduleListViewModel>();
        private List<ScheduleListViewModel> yearly_schedule_model_list = new List<ScheduleListViewModel>();

        private Project current_line = null;
        private List<DateTime> weeks = new List<DateTime>();

        private int current_selected_week = 0;

        public int CurrentSelectedWeek
        {
            get { return current_selected_week; }
            set { current_selected_week = value; }
        }

        public ProjectSelectorControlModel ProjectSelector
        {
            get { return project_selector_control_model; }
        }
        public Project CurrentLine
        {
            get { return current_line; }
        }
        public ProjectListViewModel UnscheduledProjects
        {
            get { return unscheduled_project_model; }
        }
        public ProjectListViewModel AllProjects
        {
            get { return all_project_model; }
        }

                public ScheduleListViewModel YearlyScheduleThisWeek
        {
            get { return yearly_schedule_model_list[0]; }
        }
        public ScheduleListViewModel YearlyScheduleNextWeek
        {
            get { return yearly_schedule_model_list[1]; }
        }
        public ScheduleListViewModel CommonScheduleWeek0
        {
            get { return common_schedule_model_list[0]; }
        }
        public ScheduleListViewModel CommonScheduleWeek1
        {
            get { return common_schedule_model_list[1]; }
        }
        public String ThisWeekStr
        {
            get
            {
                DateTime end = weeks[0].AddDays(6);
                return weeks[0].Month + "/" + weeks[0].Day + " - " + end.Month + "/" + end.Day + "  #" + common_schedule_model_list[0].Size;
            }
        }
        public String NextWeekStr
        {
            get
            {
                DateTime end = weeks[1].AddDays(6);
                return weeks[1].Month + "/" + weeks[1].Day + " - " + end.Month + "/" + end.Day + "  #" + common_schedule_model_list[1].Size;
            }
        }
        public int UnscheduledCount
        {
            get { return UnscheduledProjects.ProjectList.Count; }
        }
        public int AllCount
        {
            get { return AllProjects.ProjectList.Count; }
        }
        public int CurrentServiceWeek
        {
            get
            {
                DateTime base_dt = DateUtils.BaseServiceDate();
                TimeSpan ts = DateTime.Today.Subtract(base_dt);
                int d = (int)ts.TotalDays;
                return d / 7;
            }
        }
        public bool CurrentProjectAvailable
        {
            get { return current_line != null; }
        }

        public ScheduleTabViewModel()
        {
            unscheduled_project_model = new ProjectListViewModel(this);
            all_project_model = new ProjectListViewModel(this);

            project_selector_control_model = new ProjectSelectorControlModel(this);
            unscheduled_project_model.ShowAll = false;
            all_project_model.ShowAll = true;

            DateTime startweek = DateUtils.PrevDayOfWeek(DateTime.Today, DayOfWeek.Monday);
            weeks.Add(startweek);
            weeks.Add(startweek.AddDays(7));

            yearly_schedule_model_list.Add(new ScheduleListViewModel(weeks[0], Schedule.WholeYear, this));
            yearly_schedule_model_list.Add(new ScheduleListViewModel(weeks[1], Schedule.WholeYear, this));

            common_schedule_model_list.Add(new ScheduleListViewModel(weeks[0], Schedule.HalfMonth, this));
            common_schedule_model_list.Add(new ScheduleListViewModel(weeks[1], Schedule.HalfMonth, this));
        }

        public void ClearSchedule()
        {
            common_schedule_model_list[0] = new ScheduleListViewModel(weeks[0], Schedule.HalfMonth, this);
            common_schedule_model_list[1] = new ScheduleListViewModel(weeks[1], Schedule.HalfMonth, this);

            yearly_schedule_model_list[0] = new ScheduleListViewModel(weeks[0], Schedule.WholeYear, this);
            yearly_schedule_model_list[1] = new ScheduleListViewModel(weeks[1], Schedule.WholeYear, this);
        }

        public void SetLoginAccount(Resource r)
        {
            project_selector_control_model.SetLoginAccount(r);
        }

        public void SetCurrentProject(Project p, WholeLineData data)
        {
            ClearSchedule();
            current_line = p;
            if (p != null)
            {
                CoreData.Link(data, p);
                PublishData();
            }
            RaisePropertyChanged("CurrentProjectAvailable");
            RaisePropertyChanged("AllProjectTabTitle");
        }

        private int GetStandardDateDiff(DateTime dt, DateTime w0)
        {
            TimeSpan diff = dt.Date.Subtract(w0);
            int d = (int)diff.TotalDays;
            d = d % 14;
            d = (d<0) ? (d+14) : d;
            return d;
        }

        private void PublishData()
        {
            foreach (Project p in current_line.Children.Values)
            {
                if (p.PlanSchedule.ContainsKey(Schedule.HalfMonth))
                {
                    Schedule s = p.PlanSchedule[Schedule.HalfMonth];
                    int d = GetStandardDateDiff(s.PlanDate, weeks[0]);
                    int i = d / 7;
                    common_schedule_model_list[i].Add(p);
                }
                if (p.PlanSchedule.ContainsKey(Schedule.WholeYear))
                {
                    Schedule s = p.PlanSchedule[Schedule.WholeYear];
                    DateTime dt = s.PlanDate;
                    int x = DateTime.Compare(dt, weeks[0]);
                    if (x >= 0)
                    {
                        TimeSpan diff = dt.Date.Subtract(weeks[0]);
                        int d = (int)diff.TotalDays;
                        int i = d / 7;
                        if (i >= 0 && i <= 1)
                        {
                            yearly_schedule_model_list[i].Add(p);
                        }
                    }
                }
            }

            RaisePropertyChanged("YearlyScheduleThisWeek");
            RaisePropertyChanged("YearlyScheduleNextWeek");
            RaisePropertyChanged("CommonScheduleWeek0");
            RaisePropertyChanged("CommonScheduleWeek1");
            unscheduled_project_model.Parent = current_line;
            all_project_model.Parent = current_line;
            RefreshCount();
        }

        public String AllProjectTabTitle
        {
            get { return "所有设备 - " + all_project_model.Count; }
        }
        /*
        private void client_GetSchedulesByParentProjectCompleted(object sender, GetSchedulesByParentProjectCompletedEventArgs e)
        {
            ObservableCollection<ScheduleData> scheduledata_list = e.Result;
            foreach (ScheduleData sd in scheduledata_list)
            {
                Schedule s = new Schedule();
                s.Data = sd;
                Project p = Project.GetUnique(s.Data.ProjectId);
                if (p != null)
                {
                    p.PlanSchedule[s.Data.ActionType] = s;
                    s.Proj = p;
                }
            }
            foreach (Project p in current_line.Children.Values)
            {
                if (p.PlanSchedule.ContainsKey(Schedule.HalfMonth))
                {
                    Schedule s = p.PlanSchedule[Schedule.HalfMonth];
                    int d = GetStandardDateDiff(s.PlanDate, weeks[0]);
                    int i = d / 7;
                    common_schedule_model_list[i].Add(p);
                }
                if (p.PlanSchedule.ContainsKey(Schedule.WholeYear))
                {
                    Schedule s = p.PlanSchedule[Schedule.WholeYear];
                    DateTime dt = s.PlanDate;
                    int x = DateTime.Compare(dt, weeks[0]);
                    if (x >= 0)
                    {
                        TimeSpan diff = dt.Date.Subtract(weeks[0]);
                        int d = (int)diff.TotalDays;
                        int i = d / 7;
                        if (i >= 0 && i <= 1)
                        {
                            yearly_schedule_model_list[i].Add(p);
                        }
                    }

                }
            }
            RaisePropertyChanged("YearlyScheduleThisWeek");
            RaisePropertyChanged("YearlyScheduleNextWeek");
            RaisePropertyChanged("CommonScheduleWeek0");
            RaisePropertyChanged("CommonScheduleWeek1");
            unscheduled_project_model.Parent = current_line;
            all_project_model.Parent = current_line;
            RefreshCount();
        }

        private void client_GetSchedulePolicyByProjectIdCompleted(object sender, GetSchedulePolicyByProjectIdCompletedEventArgs e)
        {
            SchedulePolicyData policy_data = e.Result;
            if (policy_data == null)
            {
                policy_data = new SchedulePolicyData();
                policy_data.ProjectId = current_line.Id;
                HitachiServiceClient client = WCFClient.GetClient();
                client.SaveSchedulePolicyAsync(policy_data);
            }
            policy = new SchedulePolicy(policy_data.ProjectId);
            policy.Data = policy_data;
            common_schedule_model_list[0].Week.Policy = policy;
            common_schedule_model_list[1].Week.Policy = policy;
            yearly_schedule_model_list[0].Week.Policy = policy;
            yearly_schedule_model_list[1].Week.Policy = policy;
            common_schedule_model_list[0].Week.UpdatePolicy();
            common_schedule_model_list[1].Week.UpdatePolicy();
            yearly_schedule_model_list[0].Week.UpdatePolicy();
            yearly_schedule_model_list[1].Week.UpdatePolicy();
        }
        */
        public void RefreshCount()
        {
            RaisePropertyChanged("UnscheduledCount");
            RaisePropertyChanged("AllCount");
            RaisePropertyChanged("ThisWeekStr");
            RaisePropertyChanged("NextWeekStr");
        }

        public void Cleanup()
        {
            common_schedule_model_list[0].Week.Cleanup();
            common_schedule_model_list[1].Week.Cleanup();
            yearly_schedule_model_list[0].Week.Cleanup();
            yearly_schedule_model_list[1].Week.Cleanup();
            RaisePropertyChanged("ThisWeekStr");
            RaisePropertyChanged("NextWeekStr");
        }
        /*
        public void AddSchedule(Project project)
        {
            HitachiServiceClient client = WCFClient.GetClient();
            client.GetSchedulePolicyByProjectIdCompleted +=
                new EventHandler<GetSchedulePolicyByProjectIdCompletedEventArgs>(client_GetSchedulePolicyByProjectIdCompleted);
            client.GetSchedulePolicyByProjectIdAsync(project.Id);

            client.GetSchedulesByParentProjectCompleted +=
                new EventHandler<GetSchedulesByParentProjectCompletedEventArgs>(client_GetSchedulesByParentProjectCompleted);
            client.GetSchedulesByParentProjectAsync(project.Id);
        }
        */

        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion

    }
}
